package com.example.bluetoothclicker.func

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothServerSocket
import android.bluetooth.BluetoothSocket
import android.util.Log
import android.widget.Toast
import java.io.IOException
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

/**
 * 多设备蓝牙服务器，用于管理多个客户端连接
 * @param bluetoothAdapter 蓝牙适配器
 * @param maxConnections 最大允许连接的客户端数量
 * @param uuid 服务的 UUID，默认值适用于常见蓝牙通信
 * @param serviceName 服务名称，默认值为 "MultiBluetoothServer"
 */
class MultiBluetoothServer(
    private val bluetoothAdapter: BluetoothAdapter,
    private val maxConnections: Int,
    private val uuid: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"),
    private val serviceName: String = "MultiBluetoothServer"
) {

    // 标识服务器是否正在运行
    @Volatile
    private var isRunning = false

    // 蓝牙服务器套接字
    private var serverSocket: BluetoothServerSocket? = null

    // 用于管理线程的线程池
    private val executorService: ExecutorService = Executors.newCachedThreadPool()

    // 使用线程安全的 Map 管理客户端连接，键为 MAC 地址，值为 BluetoothSocket
    private val clientSockets: ConcurrentHashMap<String, BluetoothSocket> = ConcurrentHashMap()

    /**
     * 启动蓝牙服务器
     * @param onClientConnected 回调，当客户端连接时调用
     * @param onStatusChanged 回调，用于更新状态信息
     */
    fun startServer(
        onClientConnected: (BluetoothSocket) -> Unit,
        onStatusChanged: (String) -> Unit
    ) {
        if (isRunning) return // 如果服务器已启动，直接返回

        isRunning = true
        serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(serviceName, uuid)

        executorService.execute {
            onStatusChanged("服务器已启动")
            try {
                while (isRunning) {
                    acceptClient(onClientConnected, onStatusChanged)
                }
            } catch (e: IOException) {
                if (isRunning) onStatusChanged("服务器错误: ${e.message}")
            } finally {
                stopServer(onStatusChanged)
            }
        }
    }

    /**
     * 接收客户端连接
     * @param onClientConnected 回调，当有新客户端连接时调用
     * @param onStatusChanged 回调，用于更新状态信息
     */
    private fun acceptClient(
        onClientConnected: (BluetoothSocket) -> Unit,
        onStatusChanged: (String) -> Unit
    ) {
        if (clientSockets.size >= maxConnections) {
            onStatusChanged("已达到最大连接数: $maxConnections")
            Thread.sleep(1000) // 延迟检查，避免频繁尝试接受新连接
            return
        }

        try {
            val socket = serverSocket?.accept()
            socket?.let {
                val macAddress = it.remoteDevice.address
                // 如果客户端尚未连接，添加到连接列表
                if (clientSockets.putIfAbsent(macAddress, it) == null) {
                    onStatusChanged("客户端已连接: ${it.remoteDevice.name} [$macAddress]")
                    executorService.execute {
                        onClientConnected(it)
                    }
                } else {
                    it.close() // 如果连接已存在，关闭新连接
                }
            }
        } catch (e: IOException) {
            if (isRunning) onStatusChanged("接受连接错误: ${e.message}")
        }
    }

    /**
     * 处理客户端连接，监听消息并管理连接状态
     * @param clientSocket 客户端的套接字
     * @param macAddress 客户端的 MAC 地址
     * @param onStatusChanged 回调，用于更新状态信息
     */
    private fun handleClient(
        clientSocket: BluetoothSocket,
        macAddress: String,
        onStatusChanged: (String) -> Unit
    ) {
        try {
            val inputStream = clientSocket.inputStream
            val buffer = ByteArray(1024)
            while (isRunning && clientSocket.isConnected) {
                val bytes = inputStream.read(buffer)
                if (bytes > 0) {
                    val message = String(buffer, 0, bytes).trim()
                    onStatusChanged("来自 $macAddress 的消息: $message")
                }
            }
        } catch (e: IOException) {
            onStatusChanged("连接中断: $macAddress")
        } finally {
            closeClient(macAddress)
        }
    }

    /**
     * 停止服务器并清理资源
     * @param onStatusChanged 回调，用于更新状态信息
     */
    fun stopServer(onStatusChanged: (String) -> Unit = {}) {
        isRunning = false
        try {
            serverSocket?.close()
        } catch (e: IOException) {
            onStatusChanged("关闭服务器时发生错误: ${e.message}")
        } finally {
            serverSocket = null
        }

        // 关闭所有客户端连接
        clientSockets.keys.toList().forEach { closeClient(it) }
        executorService.shutdownNow()
        onStatusChanged("服务器已停止")
    }

    /**
     * 关闭指定客户端连接
     * @param macAddress 客户端的 MAC 地址
     */
    fun closeClient(macAddress: String) {
        clientSockets.remove(macAddress)?.let {
            try {
                it.close()
            } catch (e: IOException) {
                // 可以在这里记录日志
            }
        }
    }

    /**
     * 发送消息给指定的客户端
     * @param macAddress 客户端的 MAC 地址
     * @param message 要发送的消息
     * @return 是否发送成功
     */
    fun sendMessageToClient(macAddress: String, message: String): Boolean {
        return clientSockets[macAddress]?.let { socket ->
            try {
                socket.outputStream.write(message.toByteArray())
                true
            } catch (e: IOException) {
                closeClient(macAddress)
                false
            }
        } ?: false
    }

    /**
     * 启动服务端消息监听
     * @param onMessageReceived 回调函数，接收到消息时触发，返回 MAC 地址和消息内容
     * @param onStatusChanged 状态变更的回调函数，用于更新服务状态
     */
    fun startMessageListening(
        onMessageReceived: (macAddress: String, message: String) -> Unit,
        onStatusChanged: (status: String) -> Unit
    ) {
        if (!isRunning) {
            onStatusChanged("服务端未启动")
            Log.d("MultiBluetoothServer", "服务端未启动，消息监听未开始")
            return
        }

        executorService.execute {
            onStatusChanged("开始监听客户端消息")
            Log.d("MultiBluetoothServer", "开始监听第一个客户端消息")
            try {
                while (isRunning) {
                    val firstClientEntry = clientSockets.entries.firstOrNull() // 获取第一个客户端
                    if (firstClientEntry != null) {
                        val (macAddress, socket) = firstClientEntry
                        try {
                            if (socket.isConnected) {
                                val inputStream = socket.inputStream
                                if (inputStream.available() > 0) {
                                    Log.d("MultiBluetoothServer", "检测到来自客户端 $macAddress 的消息")
                                    val buffer = ByteArray(1024)
                                    val bytesRead = inputStream.read(buffer)
                                    if (bytesRead > 0) {
                                        val message = String(buffer, 0, bytesRead).trim()
                                        onMessageReceived(macAddress, message)
                                        onStatusChanged("来自 $macAddress 的消息: $message")
                                        Log.d("MultiBluetoothServer", "消息接收成功：$message")
                                    }
                                }
                            } else {
                                Log.w("MultiBluetoothServer", "客户端 $macAddress 已断开连接")
                                closeClient(macAddress) // 关闭断开连接的客户端
                            }
                        } catch (e: IOException) {
                            val errorMsg = "连接中断: $macAddress，错误: ${e.message}"
                            onStatusChanged(errorMsg)
                            Log.e("MultiBluetoothServer", errorMsg, e)
                            closeClient(macAddress)
                        }
                    } else {
                        Log.w("MultiBluetoothServer", "没有客户端连接")
                    }
                    Thread.sleep(100) // 避免频繁占用资源
                }
            } catch (e: Exception) {
                val errorMsg = "消息监听出错: ${e.message}"
                onStatusChanged(errorMsg)
                Log.e("MultiBluetoothServer", errorMsg, e)
            } finally {
                onStatusChanged("停止监听客户端消息")
                Log.d("MultiBluetoothServer", "监听任务结束")
            }
        }
    }




    /**
     * 停止服务端消息监听
     * @param onStatusChanged 回调函数，用于更新状态信息
     */
    fun closeMessageListening(
        onStatusChanged: (status: String) -> Unit = {}
    ) {
        if (!isRunning) {
            onStatusChanged("服务端未运行，无需停止监听")
            return
        }

        // 停止服务器和相关资源
        stopServer { status ->
            onStatusChanged(status)
        }

        // 关闭线程池，确保所有监听任务停止
        try {
            executorService.shutdownNow()
            onStatusChanged("消息监听已停止")
        } catch (e: Exception) {
            onStatusChanged("关闭监听时发生错误: ${e.message}")
        }
    }


    /**
     * 广播消息给所有客户端
     * @param message 要广播的消息
     */
    fun broadcastMessage(message: String) {
        clientSockets.forEach { (macAddress, socket) ->
            try {
                socket.outputStream.write("$message\n".toByteArray())
            } catch (e: IOException) {
                closeClient(macAddress)
            }
        }
    }

    /**
     * 获取当前已连接的客户端数量
     * @return 已连接的客户端数量
     */
    fun getConnectedCount(): Int = clientSockets.size


    /**
     * 获取指定客户端的连接套接字
     * @param macAddress 客户端的 MAC 地址
     * @return 连接的 BluetoothSocket，如果客户端未连接则返回 null
     */
    fun getClient(macAddress: String): BluetoothSocket? {
        return clientSockets[macAddress]
    }

}
